package com.eastdigit.org.service;

import com.eastdigit.org.inter.EmployeeMapper;
import com.eastdigit.org.inter.EmployeePosMapper;
import com.eastdigit.org.model.Employee;
import com.eastdigit.org.model.EmployeePos;
import com.eastdigit.servlet.ReqBean;
import com.eastdigit.system.model.BusinessException;
import com.eastdigit.system.model.IDepartment;
import com.eastdigit.system.model.SqlBuilder;
import com.eastdigit.system.service.BaseService;
import com.eastdigit.system.service.IDepartmentService;
import com.eastdigit.system.service.IEmployeeService;
import com.eastdigit.util.StringUtil;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.support.SimpleValueWrapper;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class EmployeeService extends BaseService implements IEmployeeService {

    @Autowired
    private EmployeeMapper employeeMapper;
    @Autowired
    private EmployeePosMapper employeePosMapper;
    @Autowired
    private CacheManager cacheManager;
    @Autowired
    private IDepartmentService departmentService;

    public List<Employee> queryAllEmployees() {
        // 这里手动缓存，不然在当前方法内调用缓存无效
        Cache cache = cacheManager.getCache("_empCache");
        Object value = cache.get("all");
        if (value instanceof SimpleValueWrapper) {// 存在缓存
            return (List<Employee>) ((SimpleValueWrapper) value).get();
        } else {
            List<Employee> list = employeeMapper.selectAllEmployees();
            Map<String, Employee> map = new HashMap<String, Employee>();
            for (Employee employee : list) {
                map.put(employee.getId(), employee);
            }
            for (EmployeePos pos : employeePosMapper.selectAllEmployeePos()) {
                Employee employee = map.get(pos.getEmpId());
                if (employee != null) {
                    employee.addEmployeePos(pos);
                }
            }
            cache.put("all", list);
            return list;
        }
    }

    public Employee queryEmployee(String empId) {
        for (Employee employee : queryAllEmployees()) {
            if (empId.equals(employee.getId())) {
                return employee;
            }
        }
        return null;
    }

    @Cacheable(value = "_empCache", key = "'d_' + #deptId")
    public List<Employee> queryEmployeesOfDepartment(String deptId) {
        Map<String, IDepartment> map = new HashMap<String, IDepartment>();
        List<IDepartment> list = departmentService.queryDescendantDepartmentAndSelf(deptId);
        for (IDepartment department : list) {
            map.put(department.getDeptId(), department);
        }

        List<Employee> employees = new ArrayList<Employee>();
        for (Employee employee : queryAllEmployees()) {
            for (EmployeePos pos : employee.getEmployeePos()) {
                if (deptId.equals(pos.getDeptId())) {
                    employees.add(employee);
                    break;
                }
            }

        }
        return employees;
    }

    public List<Employee> queryLeaderPosOfEmp(String empId, String posId) {
        String deptId = null;
        for (EmployeePos pos : employeePosMapper.selectByEmpId(empId)) {
            if ("1".equals(pos.getPosType())) {
                deptId = pos.getDeptId();
                break;
            }
        }
        if (deptId == null) {
            throw new BusinessException("查询员工所在部门失败！");
        }
        return queryLeaderPosOfDept(deptId, posId);
    }

    public List<Employee> queryLeaderPosOfDept(String deptId, String posId) {
        Cache cache = cacheManager.getCache("_empCache");
        Object value = cache.get(deptId + "-" + posId);
        if (value instanceof SimpleValueWrapper) {// 存在缓存
            return (List<Employee>) ((SimpleValueWrapper) value).get();
        } else {
            Map<String, List<Employee>> map = new HashMap<String, List<Employee>>();
            for (EmployeePos pos : employeePosMapper.selectByPosId(posId)) {
                if (posId.equals(pos.getPosId())) {
                    List<Employee> list = map.get(pos.getDeptId());
                    if (list == null) {
                        list = new ArrayList<Employee>();
                        map.put(pos.getDeptId(), list);
                    }
                    list.add(queryEmployee(pos.getEmpId()));
                }
            }
            List<Employee> list = queryLeaderPosOfDept(map, departmentService.queryDepartment(deptId));
            cache.put(deptId + "-" + posId, list);
            return list;
        }
    }

    private List<Employee> queryLeaderPosOfDept(Map<String, List<Employee>> map, IDepartment department) {
        if (department != null) {
            if (map.containsKey(department.getDeptId())) {
                return map.get(department.getDeptId());
            } else {
                return queryLeaderPosOfDept(map, departmentService.queryDepartment(department.getParentDeptId()));
            }
        }
        return null;
    }

    /**
     * 查询员工(条件，分页)
     * 
     * @param reqBean
     * @return
     */
    public JSONObject queryEmp(ReqBean reqBean) {
        String deptId = reqBean.getInfo("deptId");
        String codeOrName = StringUtils.trimToEmpty(reqBean.getInfo("codeOrName"));

        SqlBuilder sqlBuilder = new SqlBuilder("select * from SYS_EMPLOYEE a where 1 = 1 ");

        sqlBuilder.appendSql(" and exists(select 1 from SYS_EMPLOYEE_POS a where EMP_ID = a.EMP_ID").addWhereDataScope(
                "a.DEPT_ID", reqBean);
        if (StringUtil.isNotEmpty(deptId)) {
            List<IDepartment> list = departmentService.queryDescendantDepartmentAndSelf(deptId);
            if (list.size() > 0) {
                Object[] deptIds = new Object[list.size()];
                for (int i = 0; i < list.size(); i++) {
                    deptIds[i] = list.get(i).getDeptId();
                }
                sqlBuilder.addWhereIn("DEPT_ID", deptIds);
            }
        }
        sqlBuilder.appendSql(")");

        if (StringUtils.isNotBlank(codeOrName)) {
            sqlBuilder.appendSql(" and (EMP_CODE = ? or EMP_NAME like ?)", codeOrName, "%" + codeOrName + "%");
        }
        sqlBuilder.orderBy(" order by EMP_NAME");

        JSONObject jsonObject = queryTable(sqlBuilder, reqBean.getPageSize(), reqBean.getPageIndex());
        Map<String, JSONObject> map = new HashMap<String, JSONObject>();
        JSONArray row = jsonObject.getJSONArray("rows");
        if(row != null && row.size() > 0) {
            for (int i = 0; i < row.size(); i++) {
                JSONObject json = row.getJSONObject(i);
                map.put(json.getString("empId"), json);
            }

            List<Object> ids = new ArrayList<Object>();
            ids.addAll(map.keySet());
            sqlBuilder = new SqlBuilder(
                    "select a.*, (select DEPT_NAME from SYS_DEPARTMENT where DEPT_ID = a.DEPT_ID) DEPT_NAME from SYS_EMPLOYEE_POS a where 1 = 1")
                    .addWhereIn("EMP_ID", ids).orderBy(" order by EMP_ID, POS_TYPE desc");
            JSONArray array = query(sqlBuilder);
            for (int i = 0; i < array.size(); i++) {
                JSONObject json = array.getJSONObject(i);
                JSONObject emp = map.get(json.getString("empId"));
                JSONArray pos = emp.optJSONArray("poses");
                if (pos == null) {
                    pos = new JSONArray();
                }
                pos.add(json);
                emp.put("poses", pos);
            }
        }
        return jsonObject;
    }

    /**
     * 新增员工
     * 
     * @param reqBean
     */
    @CacheEvict(value = "_empCache", allEntries = true)
    public void addEmp(ReqBean reqBean) {
        Employee employee = getEmp(reqBean);
        employee.setId(intIncrementId("SYS_EMPLOYEE", "EMP_ID"));
        employee.setMakeTime(employee.getModifyTime());

        employeeMapper.insert(employee);
        // 添加岗位
        addPos(employee.getEmpId(), reqBean);
    }

    /**
     * 修改员工
     * 
     * @param reqBean
     */
    @CacheEvict(value = "_empCache", allEntries = true)
    public void updateEmp(ReqBean reqBean) {
        String employeeId = reqBean.getInfo("empId");
        if (StringUtil.isEmpty(employeeId)) {
            throw new BusinessException("获取主键失败");
        }
        Employee employee = getEmp(reqBean);
        employeeMapper.updateByPrimaryKeySelective(employee);

        // 删除用户岗位
        employeePosMapper.deleteByEmpId(employeeId);
        // 添加岗位
        addPos(employeeId, reqBean);
    }

    /**
     * 添加岗位
     * 
     * @param empId
     * @param reqBean
     */
    private void addPos(String empId, ReqBean reqBean) {
        String poses = reqBean.getInfo("poses");
        if (StringUtil.isEmpty(poses)) {
            throw new BusinessException("请设置岗位");
        }
        JSONArray array = JSONArray.fromObject(poses);
        if (array == null || array.size() == 0) {
            throw new BusinessException("请设置岗位");
        }
        for (int i = 0; i < array.size(); i++) {
            JSONObject json = array.getJSONObject(i);
            EmployeePos pos = new EmployeePos();
            pos.setEmpId(empId);
            pos.setDeptId(json.getString("deptId"));
            pos.setPosId(json.getString("posId"));
            pos.setPosType(i == 0 ? "1" : "0");
            employeePosMapper.insert(pos);
        }

    }

    /**
     * 删除员工
     * 
     * @param reqBean
     */
    @CacheEvict(value = "_empCache", allEntries = true)
    public void deleteEmp(ReqBean reqBean) {
        String employeeId = reqBean.getInfo("empId");
        if (StringUtil.isEmpty(employeeId)) {
            throw new BusinessException("获取主键失败");
        }
        // 删除用户岗位
        employeePosMapper.deleteByEmpId(employeeId);

        employeeMapper.deleteByPrimaryKey(employeeId);
    }

    /**
     * 获取指定员工
     * 
     * @param reqBean
     * @return
     */
    private Employee getEmp(ReqBean reqBean) {
        Employee employee = new Employee();
        employee.setId(reqBean.getInfo("empId"));
        employee.setCode(reqBean.getInfo("empCode"));
        employee.setName(reqBean.getInfo("empName"));
        employee.setGender(reqBean.getInfo("gender"));
        employee.setTelephone(reqBean.getInfo("telephone"));
        employee.setMobile1(reqBean.getInfo("mobile1"));
        employee.setMobile2(reqBean.getInfo("mobile2"));
        employee.setEmail(reqBean.getInfo("email"));
        employee.setState(reqBean.getInfo("empState"));
        employee.setOperator(reqBean.getUserId());
        employee.setModifyTime(new Date());
        employee.setRemark(reqBean.getInfo("remark"));
        employee.setExtra1(reqBean.getInfo("extra1"));
        employee.setExtra2(reqBean.getInfo("extra2"));
        return employee;
    }

}
